class_name Card
extends Control

signal joinHand(which: Card)

const BASE := preload ("res://tres/cards/card.tres")
const DRAG := preload ("res://tres/cards/cardDrag.tres")
const HOVER := preload ("res://tres/cards/cardHover.tres")

@export var cardSrc: CardSrc: set = _setCardSrc

@onready var cost: Label = $Cost
@onready var icon: TextureRect = $Icon
@onready var panel: Panel = $Panel
@onready var dropArea: Area2D = $DrapArea
@onready var machine: StateMachine = $StateMachine
var index := 0

var stats: PlayerStatsSrc
var parent: Control
var tween: Tween
# 玩家是否能打出该卡
var playabel := true: set = _setPlayable
# 卡牌是否禁用
var disable := false
# 卡牌进入的区域
var placeArea: Area2D

func _ready() -> void:
	# 连接卡牌操作的生母周期信号
	Events.cardDragStarted.connect(onCardActionStarted)
	Events.cardDragEnded.connect(onCardActionEnded)
	Events.cardAimStarted.connect(onCardActionStarted)
	Events.cardAimEnded.connect(onCardActionEnded)
	# 获取并订阅玩家的状态面板
	stats = Game.player.statsSrc
	stats.statsChanged.connect(onPlayerStatsChange)
	# 初始化状态机
	machine.init(self)

func _input(event: InputEvent) -> void:
	machine.onInput(event)

func onGuiInput(event: InputEvent) -> void:
	machine.onGuiInput(event)

func onMouseEntered() -> void:
	machine.onMouseEntered()
	Events.showTip.emit(cardSrc.icon, cardSrc.desc)

func onMouseExited() -> void:
	machine.onMouseExited()
	Events.hideTip.emit()

# 缓动动画
func tweenToPos(target: Vector2, duration: float) -> void:
	tween = create_tween().set_trans(Tween.TRANS_CIRC).set_ease(Tween.EASE_OUT)
	tween.tween_property(self, "global_position", target, duration)

# 获取卡牌资源
func _setCardSrc(val: CardSrc) -> void:
	if !is_node_ready(): await ready
	cardSrc = val
	cost.text = str(val.cost)
	icon.texture = val.icon

# 卡牌是否可打出 样式变化
func _setPlayable(val: bool) -> void:
	playabel = val
	if !playabel:
		cost.add_theme_color_override("font_color", Color.RED)
		icon.modulate = Color(1, 1, 1, .5)
	else:
		cost.remove_theme_color_override("font_color")
		icon.modulate = Color(1, 1, 1, 1)

# 卡牌进入放置区
func _on_drap_area_area_entered(area: Area2D):
	if placeArea: push_error('放置区已存在', placeArea)
	placeArea = area
# 卡牌离开放置区
func _on_drap_area_area_exited(area: Area2D):
	if area != placeArea: push_error('放置区不一致', placeArea)
	placeArea = null

# 卡牌打出
func play() -> void:
	if !cardSrc: return
	cardSrc.play([placeArea], stats)
	queue_free()

# 动作开始时禁用其他卡牌
func onCardActionStarted(card: Card) -> void:
	if card == self: return
	disable = true

# 动作结束时解禁卡牌
func onCardActionEnded(_card: Card) -> void:
	disable = false

# 数据变化时从新计算卡牌的可用性
func onPlayerStatsChange() -> void:
	self.playabel = stats.canPlay(cardSrc)
